package com.step.mesh.buffer;

import java.nio.ByteBuffer;

import com.step.mesh.Color;
import com.step.utils.BufferUtils;

public class ColorBuffer {
	static final int PROPERTIES_PER_ELEMENT = 4;
	static final int BYTES_PER_PROPERTY = 1;
	private ByteBuffer byteBuffer;
	private int numElements;
	
	/**
	 * 创建颜色缓冲区
	 * @param byteBuffer 字节数组
	 * @param size 颜色个数
	 */
	public ColorBuffer(ByteBuffer byteBuffer, int size)	{
		this.byteBuffer = BufferUtils.newByteBuffer(byteBuffer.limit());
		this.byteBuffer.put(byteBuffer);
		this.numElements = size;
	}
	
	/**
	 * 创建颜色缓冲区
	 * @param maxElements 最大保存的颜色个数
	 */
	public ColorBuffer(int maxElements){
		int numBytes = maxElements * PROPERTIES_PER_ELEMENT;
		this.byteBuffer = BufferUtils.newByteBuffer(numBytes);
	}
	
	/**
	 * 返回颜色个数 
	 */
	public int size(){
		return numElements;
	}
	
	/**
	 * 返回可容纳颜色的个数
	 */
	public int capacity()	{
		return byteBuffer.capacity() / PROPERTIES_PER_ELEMENT;
	}
	
	/**
	 * 清空缓存，以便回收垃圾
	 */
	public void clear(){
		byteBuffer.clear();
	}

	/**
	 * 获取颜色
	 * @param index 索引位置
	 * @return
	 */
	public Color getColor(int index){
		byteBuffer.position(index * PROPERTIES_PER_ELEMENT);
		return new Color( byteBuffer.get(), byteBuffer.get(), byteBuffer.get(), byteBuffer.get() );
	}
	
	/**
	 * 获取颜色
	 * @param index 索引位置
	 * @param color 取得的颜色
	 */
	public void getColor(int index, Color color){
		byteBuffer.position(index * PROPERTIES_PER_ELEMENT);
		color.r = (short)byteBuffer.get();
		color.g = (short)byteBuffer.get();
		color.b = (short)byteBuffer.get();
		color.a = (short)byteBuffer.get();
	}

	/**
	 * 获取红色分量
	 * @param index 索引位置
	 * @return
	 */
	public short getRed(int index){
		byteBuffer.position(index * PROPERTIES_PER_ELEMENT);
		return (short)byteBuffer.get();
	}
	
	/**
	 * 获取绿色分量
	 * @param index 索引位置
	 * @return
	 */
	public short getGreen(int index){
		byteBuffer.position(index * PROPERTIES_PER_ELEMENT + 1);
		return (short)byteBuffer.get();
	}
	
	/**
	 * 获取蓝色分量
	 * @param index 索引位置
	 * @return
	 */
	public float getPropertyB(int index){
		byteBuffer.position(index * PROPERTIES_PER_ELEMENT + 2);
		return (short)byteBuffer.get();
	}
	
	/**
	 * 获取透明度分量
	 * @param index 索引位置
	 * @return
	 */
	public float getAlpha(int index){
		byteBuffer.position(index * PROPERTIES_PER_ELEMENT + 3);
		return (short)byteBuffer.get();
	}
	
	/**
	 * 添加颜色
	 * @param color
	 */
	public void add(Color color){
		set(numElements, color);
		numElements++;
	}
	
	/**
	 * 添加颜色
	 * @param red 红色分量
	 * @param green 绿色分量
	 * @param blue 蓝色分量
	 * @param alpha 透明度分量
	 */
	public void add(short red, short green, short blue, short alpha)	{
		set(numElements, red, green, blue, alpha);
		numElements++;
	}
	
	public void add(int red, int green, int blue, int alpha){
		set(numElements, (short)red, (short)green, (short)blue, (short)alpha);
		numElements++;
	}
	
	/**
	 * 设置颜色
	 * @param index 索引位置
	 * @param color 颜色
	 */
	public void set(int index, Color color){
		byteBuffer.position(index * PROPERTIES_PER_ELEMENT);
		byteBuffer.put((byte)color.r);
		byteBuffer.put((byte)color.g);
		byteBuffer.put((byte)color.b);
		byteBuffer.put((byte)color.a);		
		// Rem, OpenGL takes in color in this order: r,g,b,a -- _not_ a,r,g,b
	}

	/**
	 * 设置颜色
	 * @param index 索引位置
	 * @param red 红色分量
	 * @param green 绿色分量
	 * @param blue 蓝色分量
	 * @param alpha 透明度分量
	 */
	public void set(int index, short red, short green, short blue, short alpha)	{
		byteBuffer.position(index * PROPERTIES_PER_ELEMENT);
		byteBuffer.put((byte)red);
		byteBuffer.put((byte)green);
		byteBuffer.put((byte)blue);
		byteBuffer.put((byte)alpha);
	}
	
	public void setRed(int index, short red){
		byteBuffer.position(index * PROPERTIES_PER_ELEMENT);
		byteBuffer.put((byte)red);
	}
	
	public void setPropertyG(int index, short green){
		byteBuffer.position(index * PROPERTIES_PER_ELEMENT + 1);
		byteBuffer.put((byte)green);
	}
	
	public void setPropertyB(int index, short blue)	{
		byteBuffer.position(index * PROPERTIES_PER_ELEMENT + 2);
		byteBuffer.put((byte)blue);
	}
	
	public void setPropertyA(int index, short alpha){
		byteBuffer.position(index * PROPERTIES_PER_ELEMENT + 3);
		byteBuffer.put((byte)alpha);
	}
	
	/**
	 * 获取字节缓存内容
	 * @return
	 */
	public ByteBuffer buffer()	{
		return byteBuffer;
	}
	
	public ColorBuffer clone()	{
		byteBuffer.position(0);
		ColorBuffer c = new ColorBuffer(byteBuffer, size());
		return c;
	}
}
